package com.timebank.volunteer.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.timebank.common.core.constant.*;
import com.timebank.common.core.constant.rabbitmq.exchange.ExchangeConstant;
import com.timebank.common.core.constant.rabbitmq.routingkey.RoutingKeyConstant;
import com.timebank.common.core.constant.score.task.ScoreTaskConstant;
import com.timebank.common.core.exception.ServiceException;
import com.timebank.common.core.exception.volunteer.*;
import com.timebank.common.core.result.Result;
import com.timebank.common.core.utils.StringUtils;
import com.timebank.common.core.web.pojo.AjaxResult;
import com.timebank.score.pojo.entity.ScoreTaskLog;
import com.timebank.score.service.RemoteScoreTaskLogService;
import com.timebank.system.pojo.SysUser;
import com.timebank.common.core.constant.message.MessageTypeConstant;
import com.timebank.volunteer.constant.SenderAndGetterConstant;
import com.timebank.volunteer.constant.SortConstant;
import com.timebank.volunteer.constant.URLConstant;
import com.timebank.volunteer.pojo.dto.ExamineDTO;
import com.timebank.volunteer.pojo.dto.VolunteerDTO;
import com.timebank.volunteer.pojo.dto.VolunteerSignDTO;
import com.timebank.volunteer.pojo.entity.*;
import com.timebank.common.security.utils.SecurityUtils;
import com.timebank.system.model.LoginUser;
import com.timebank.system.service.RemoteUserService;
import com.timebank.volunteer.mapper.VolunteerListMapper;
import com.timebank.volunteer.mapper.VolunteerMapper;
import com.timebank.volunteer.pojo.vo.VolunteerBlackListVO;
import com.timebank.volunteer.pojo.vo.VolunteerSignListVO;
import com.timebank.volunteer.pojo.vo.VolunteerVO;
import com.timebank.volunteer.service.VolunteerBlackListService;
import com.timebank.volunteer.service.VolunteerService;
import com.timebank.volunteer.service.VolunteerSignListService;
import com.timebank.volunteer.utils.GaoDeMapUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author shiliuyinzhen
 */
@Service
public class VolunteerServiceImpl implements VolunteerService{

    @Resource
    private VolunteerMapper volunteerMapper;

    @Resource
    private VolunteerListMapper volunteerListMapper;

    @Resource
    private VolunteerSignListService volunteerSignListService;

    @Resource
    private VolunteerBlackListService volunteerBlackListService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private GaoDeMapUtil gaoDeMapUtil;

    @Resource
    private RemoteUserService remoteUserService;

    @Resource
    private RemoteScoreTaskLogService remoteScoreTaskLogService;

    /**
     * 根据id获取志愿服务
     * @param volunteerId
     * @return
     */
    @Override
    public VolunteerVO getVolunteerById(Long volunteerId) {
        VolunteerVO volunteer = volunteerMapper.getVolunteerById(volunteerId);
        volunteer.setSignUp(false);
        volunteer.setSignIn(false);
        String token = SecurityUtils.getToken();
        Long userId = SecurityUtils.getUserId();
        if (token != null && token != "" && userId > 0){
            VolunteerList volunteerList = VolunteerList.builder()
                    .volunteerId(volunteerId)
                    .userId(SecurityUtils.getUserId())
                    .delFlag(StatusConstant.DISABLE)
                    .build();
            volunteerList = volunteerListMapper.getVolunteerList(volunteerList);
            if(volunteerList != null){
                volunteer.setSignUp(true);
            }
            //设置是否签到
            Boolean signIn = volunteerSignListService.checkSign(volunteerId, userId);
            volunteer.setSignIn(signIn);
        }
        return volunteer;
    }

    /**
     * 分页查询志愿服务列表
     *
     * @param volunteerDTO
     * @return
     */
    @Override
    public List<Volunteer> selectVolunteerList(VolunteerDTO volunteerDTO) {
        //默认创建时间降序
        if (volunteerDTO.getIsCreateTimeDesc() == null){
            volunteerDTO.setIsCreateTimeDesc(SortConstant.IS_DESC);
        }
        if (volunteerDTO.getParams() != null){
            String status = (String) volunteerDTO.getParams().get("status");
            if (status != null && status != ""){
                volunteerDTO.getParams().put("currentTime",LocalDateTime.now());
            }
        }
        //如果没有状态，默认审核通过
        if (volunteerDTO.getStatus() == null
                || volunteerDTO.getStatus() < 0){
            volunteerDTO.setStatus(VolunteerStatusConstant.APPROVE_PASSED);
        }
        List<Volunteer> volunteers =
                volunteerMapper.selectVolunteerList(volunteerDTO);
        String location = volunteerDTO.getLocation();
        //如果location不为空字符串也不为null
        if ( location != null && location != ""){
            for (Volunteer volunteer : volunteers) {
                Long distance =
                        gaoDeMapUtil.getDistance(location, volunteer.getLocation());
                volunteer.setDistance(distance);
                //如果在距离之外
                if (volunteerDTO.getDistance() != null
                    && volunteerDTO.getDistance() > 0
                    && volunteerDTO.getDistance() < distance){
                    //删除志愿服务
                    volunteers.remove(volunteer);
                }
            }
        }
        return volunteers;
    }

    /**
     * 新增志愿服务
     * @param volunteerDTO
     * @return
     */
    @Override
    @Transactional
    public AjaxResult insertVolunteer(VolunteerDTO volunteerDTO) throws JsonProcessingException {

        //检验支付密码
        checkPayPassword(volunteerDTO);

        //检验志愿服务信息
        Volunteer volunteer = checkVolunteer(volunteerDTO);
        //设置创建人
        volunteer.setCreateBy(SecurityUtils.getUsername());
        //设置创建时间
        volunteer.setCreateTime(LocalDateTime.now());
        //设置发布人id
        volunteer.setPublisherId(SecurityUtils.getUserId());
        //设置经纬度
        String location = volunteer.getLocation();
        if ( location == null || location == ""){
            GeocodeResponse geocodeResponse =
                    gaoDeMapUtil.getLocationByAddress(volunteer.getAddress());
            volunteer.setLocation(geocodeResponse.getGeocodes().getLocation());
        }
        // 插入志愿服务
        int row = volunteerMapper.insertVolunteerService(volunteer);
        if (row > 0){
            String url = URLConstant.VOLUNTEER_SERVICE_BASE_URL + "/" + volunteer.getId();
            //推送志愿服务已发布通知
            StringBuffer content = new StringBuffer();
            content.append("发布志愿服务:" + volunteer);
            VolunteerMessage msg = VolunteerMessage.builder()
                    .volunteerId(volunteer.getId().toString())
                    .title("发布志愿服务成功")
                    .typeId(MessageTypeConstant.VOLUNTEER_INSERT)
                    .senderId(SecurityUtils.getUserId())
                    .senderName(SecurityUtils.getUsername())
                    .getterId(SenderAndGetterConstant.PUBLISHER)
                    .content(content.toString())
                    .url(url)
                    .build();
            //将消息转换为json格式
            String msgJSON = JSON.toJSONString(msg);
            //向志愿服务参与者，发出通知
            rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE,RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
            //新增完成发布志愿服务任务记录
            ScoreTaskLog scoreTaskLog = ScoreTaskLog.builder()
                    .taskId(ScoreTaskConstant.PUBLISH_VOLUNTEER)
                    .userId(SecurityUtils.getUserId())
                    .finishTime(LocalDateTime.now())
                    .remark("完成发布志愿服务")
                    .build();
            AjaxResult ajaxResult =
                    remoteScoreTaskLogService.addScoreTaskLog(scoreTaskLog,SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServiceException("记录完成积分任务失败");
            }
        }
        return row > 0 ? AjaxResult.success("发布成功") : AjaxResult.error("发布失败");
    }

    /**
     * 校验支付密码
     * @param volunteerDTO
     */
    private void checkPayPassword(VolunteerDTO volunteerDTO) {
        Result<LoginUser> result =
                remoteUserService.getUserInfo(SecurityUtils.getUsername(), SecurityConstants.INNER);
        SysUser sysUser = result.getData().getSysUser();
        String userPayPassword = sysUser.getPayPassword();

        if (userPayPassword == null ||  sysUser.getPayPassword() == ""){
            throw new ServiceException("请先设置支付密码");
        }

        String payPassword = volunteerDTO.getPayPassword();
        if ( payPassword == null || payPassword == ""){
            throw new ServiceException("支付密码不能为空");
        }

        List<Long> userIds = new ArrayList<>();
        userIds.add(SecurityUtils.getUserId());

        if (!SecurityUtils.matchesPassword(payPassword,sysUser.getPayPassword())){
            throw new ServiceException("支付密码错误");
        }
    }

    /**
     * 修改志愿服务封面
     * @param cover
     * @param volunteerId
     * @return
     */
    @Override
    public int updateVolunteerCoverById(String cover, Long volunteerId) {
        return volunteerMapper.updateVolunteerCoverById(cover,volunteerId);
    }

    /**
     * 修改志愿服务信息
     * @param volunteerDTO
     * @return
     */
    @Override
    public int updateVolunteerById(Long volunteerId, VolunteerDTO volunteerDTO) throws JsonProcessingException {
        //查询志愿服务
        Volunteer volunteer1 = volunteerMapper.getVolunteerById(volunteerId);
        LocalDateTime beginTime = volunteer1.getBeginTime();
        //如果志愿服务已经开始
        if (LocalDateTime.now().isAfter(beginTime)){
            throw new ServiceException("志愿服务已经开始，不能进行修改");
        }
        //检验志愿服务信息
        Volunteer volunteer = checkVolunteer(volunteerDTO);
        volunteer.setId(volunteerId);
        int row = volunteerMapper.updateVolunteerById(volunteer);
        if (row > 0){
            String url = URLConstant.VOLUNTEER_SERVICE_BASE_URL + "/" + volunteerId;
            //推送志愿服务信息已修改通知
            StringBuffer content = new StringBuffer();
            content.append("您报名的志愿服务：")
                    .append("《")
                    .append(volunteer1.getTitle())
                    .append("》")
                    .append("部分信息已进行修改，可点击链接进行查看:")
                    .append(url);
            VolunteerMessage msg = VolunteerMessage.builder()
                    .volunteerId(volunteerId.toString())
                    .title("志愿服务信息已修改")
                    .typeId(MessageTypeConstant.VOLUNTEER_UPDATE)
                    .senderId(SecurityUtils.getUserId())
                    .senderName(SecurityUtils.getUsername())
                    .getterId(SenderAndGetterConstant.VOLUNTEER_LIST)
                    .content(content.toString())
                    .url(url)
                    .build();
            //将消息转换为json格式
            String msgJSON = JSON.toJSONString(msg);
            //向志愿服务参与者，发出通知
            rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE, RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
        }
        return row;
    }

    /**
     * 检验志愿服务信息
     * @param volunteerDTO
     * @return
     */
    private Volunteer checkVolunteer(VolunteerDTO volunteerDTO) {

        LocalDateTime beginTime = volunteerDTO.getBeginTime();
        LocalDateTime endTime = volunteerDTO.getEndTime();
        LocalDateTime deadline = volunteerDTO.getDeadline();

        //如果志愿服务开始时间、结束时间或者报名截止时间为空
        if (beginTime == null || endTime == null || deadline == null){
            throw new VolunteerTimeException(VolunteerExceptionConstant.TIME_IS_NULL);
        }
        //如果志愿服务开始时间小于结束时间
        if (beginTime.isAfter(endTime)){
            throw new VolunteerTimeException(VolunteerExceptionConstant.BEGIN_END_TIME_NOT_VALID);
        }
        //如果报名截止时间小于开始时间
        if (deadline.isAfter(beginTime)){
            throw new VolunteerTimeException(VolunteerExceptionConstant.DEADLINE_NOT_VALID);
        }
        //如果志愿人数小于等于0
        if (volunteerDTO.getVolunteerNum() <= 0){
            throw new VolunteerNumException(VolunteerExceptionConstant.VOLUNTEER_NUM_LESSER_ZERO);
        }
        //如果时间币数量小于等于0
        if (volunteerDTO.getTimeCoin() <= 0){
            throw new VolunteerTimeCoinException(VolunteerExceptionConstant.TIME_COIN_NUM_LESSER_ZERO);
        }
        //查询当前用户登录信息
        Result<LoginUser> userResult = remoteUserService.getUserInfo(SecurityUtils.getUsername(), SecurityConstants.INNER);
        //获取用户时间币余额
        Integer timeCoin =  userResult.getData().getSysUser().getTimeCoin();
        //计算出志愿服务总花费时间币数量
        Integer totalTimeCoin = volunteerDTO.getVolunteerNum() * volunteerDTO.getTimeCoin();
        //如果用户时间币余额不足以支付志愿服务
        if (timeCoin < totalTimeCoin){
            throw new VolunteerTimeCoinException(VolunteerExceptionConstant.USER_TIME_COIN_NOT_ENOUGH);
        }
        Volunteer volunteer = new Volunteer();
        BeanUtils.copyProperties(volunteerDTO,volunteer);
        volunteer.setUpdateBy(SecurityUtils.getUsername());
        volunteer.setUpdateTime(LocalDateTime.now());
        return volunteer;
    }

    /**
     * 批量删除志愿服务
     * @param volunteerIds
     * @return
     */
    @Override
    @Transactional
    public AjaxResult deleteVolunteerByIds(Long[] volunteerIds) {
        Long userId = SecurityUtils.getUserId();
        //查询用户信息
        Result<LoginUser> result =
                remoteUserService.getUserInfo(SecurityUtils.getUsername(), SecurityConstants.INNER);
        if (result == null
                || result.getData() == null
                || result.getData().getSysUser() == null){
            throw new ServiceException("查询用户信息失败");
        }
        SysUser sysUser = result.getData().getSysUser();
        Integer role = sysUser.getRole();
        //查询志愿服务
        List<Volunteer> volunteers = volunteerMapper.getVolunteerByIds(volunteerIds);
        //如果不是管理员或者超级管理员
        if (!(SecurityUtils.isAdmin(userId) || role.equals(999L))){
            for (Volunteer volunteer : volunteers) {
                //如果发布者不是该用户
                if (volunteer.getPublisherId() != userId){
                    throw new VolunteerException(VolunteerExceptionConstant.USER_NOT_HAVE_PERMISSION);
                }
            }
        }
        //创建消息，异步执行
        String volunteerIdsStr = StringUtils.join(volunteerIds, ",");
        VolunteerMessage msg = VolunteerMessage.builder()
                .volunteerId(volunteerIdsStr)
                .senderId(SecurityUtils.getUserId())
                .senderName(SecurityUtils.getUsername())
                .getterId(SenderAndGetterConstant.VOLUNTEER_LIST)
                .typeId(MessageTypeConstant.VOLUNTEER_DELETE)
                .title("取消发布志愿服务")
                .content("取消发布志愿服务")
                .build();
        //将消息转换为json格式
        String msgJSON = JSON.toJSONString(msg);
        //向志愿服务参与者，发出通知
        rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE, RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
        //删除志愿服务
        return volunteerMapper.deleteVolunteerByIds(volunteerIds) > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 报名志愿服务
     * @param volunteerId
     * @return
     */
    @Override
    @Transactional
    public AjaxResult signUpVolunteer(Long volunteerId) {
        //查询当前志愿服务报名人数是否已满
        Volunteer volunteer = volunteerMapper.selectVolunteerById(volunteerId);
        //如果找不到志愿服务
        if (volunteer == null){
            throw new VolunteerNotFoundException(VolunteerExceptionConstant.VOLUNTEER_NOT_FOUND + ",志愿服务id:" + volunteerId);
        }
        Integer status = volunteer.getStatus();
        //如果志愿服务状态不是通过审核
        if (status != VolunteerStatusConstant.APPROVE_PASSED){
            throw new VolunteerNotFoundException(VolunteerExceptionConstant.VOLUNTEER_NOT_FOUND);
        }
        //查询黑名单
        List<VolunteerBlackListVO> blackList = volunteerBlackListService.getBlackListByVolunteerIdAndUserId(volunteerId, SecurityUtils.getUserId());
        //如果查询结果不为空
        if (!blackList.isEmpty()){
            //已被拉入黑名单
            throw new VolunteerException(VolunteerExceptionConstant.USER_IS_IN_BLACK_LIST);
        }
        //如果报名已经截止
        if (LocalDateTime.now().isAfter(volunteer.getDeadline())){
            throw new VolunteerSignUpHasEndedException(VolunteerExceptionConstant.VOLUNTEER_SIGN_UP_HAS_ENDED + ",报名失败");
        }
        //如果人数已满
        if (volunteer.getCurrentVolunteerNum() + 1 > volunteer.getVolunteerNum()){
            throw new VolunteerNumException(VolunteerExceptionConstant.VOLUNTEER_IS_FULL);
        }
        VolunteerList volunteerList = VolunteerList.builder()
                .volunteerId(volunteerId)
                .userId(SecurityUtils.getUserId())
                .createId(999L)
                .createBy("system")
                .remark("报名志愿服务")
                .build();
        //查询志愿服务参与列表是否包含用户id
        List<VolunteerList> list = volunteerListMapper.selectVolunteerList(volunteerList);
        //如果已经报名成功
        if (list.size() > 0){
            throw new VolunteerHasSignedUpException(VolunteerExceptionConstant.VOLUNTEER_HAS_SIGNED_UP);
        }
        int currentVolunteerNum = volunteer.getCurrentVolunteerNum() + 1;
        //如果志愿人数已满
        if (currentVolunteerNum > volunteer.getVolunteerNum()){
            //设置状态为志愿人数已满
            volunteer.setStatus(VolunteerStatusConstant.VOLUNTEER_IS_FULL);
        }
        volunteer.setCurrentVolunteerNum(currentVolunteerNum);
        //更新当前志愿服务人数
        volunteerMapper.updateVolunteerById(volunteer);
        volunteerList.setCreateTime(LocalDateTime.now());
        //更新志愿服务参与名单
        int row = volunteerListMapper.signUpVolunteer(volunteerList);
        //新增任务记录
        if (row > 0){
            ScoreTaskLog scoreTaskLog = ScoreTaskLog.builder()
                    .taskId(ScoreTaskConstant.SIGN_UP_VOLUNTEER)
                    .userId(SecurityUtils.getUserId())
                    .finishTime(LocalDateTime.now())
                    .remark("完成报名志愿服务")
                    .build();
            AjaxResult ajaxResult =
                    remoteScoreTaskLogService.addScoreTaskLog(scoreTaskLog,SecurityConstants.INNER);
            if (ajaxResult.isError()){
                throw new ServiceException("记录完成积分任务失败");
            }
        }
        return  row > 0 ? AjaxResult.success("报名成功") : AjaxResult.error("报名失败");
    }

    /**
     * 取消报名志愿服务
     * @param volunteerId
     * @return
     */
    @Override
    @Transactional
    public AjaxResult cancelSignUpVolunteer(Long volunteerId) {
        //查询当前志愿服务信息
        Volunteer volunteer = volunteerMapper.selectVolunteerById(volunteerId);
        //如果找不到志愿服务
        if (volunteer == null){
            throw new VolunteerNotFoundException(VolunteerExceptionConstant.VOLUNTEER_NOT_FOUND + ",志愿服务id:" + volunteerId);
        }
        VolunteerList volunteerList = new VolunteerList();
        volunteerList.setVolunteerId(volunteerId);
        volunteerList.setUserId(SecurityUtils.getUserId());
        //查询志愿服务参与列表是否包含用户id
        List<VolunteerList> list = volunteerListMapper.selectVolunteerList(volunteerList);
        //如果未报名该志愿服务
        if (list.size() == 0){
            throw new VolunteerNotSignedUpException(VolunteerExceptionConstant.VOLUNTEER_NOT_SIGN_UP);
        }
        //如果志愿服务报名已经截止
        if (LocalDateTime.now().isAfter(volunteer.getDeadline())){
            throw new VolunteerHasBeganException(VolunteerExceptionConstant.VOLUNTEER_SIGN_UP_HAS_ENDED+ ",取消报名失败");
        }
        volunteer.setCurrentVolunteerNum(volunteer.getCurrentVolunteerNum() - 1);
        //更新当前志愿服务人数
        volunteerMapper.updateVolunteerById(volunteer);
        //更新志愿服务参与名单
        return volunteerListMapper.cancelSignUpVolunteer(volunteerList) > 0 ? AjaxResult.success("取消报名成功") : AjaxResult.error("取消报名失败");
    }

    /**
     * 获取已报名志愿服务列表
     *
     * @return
     */
    @Override
    public List<VolunteerVO> getSignUpVolunteerList(VolunteerDTO volunteerDTO) {
        //默认创建时间降序
        if (volunteerDTO.getIsCreateTimeDesc() == null){
            volunteerDTO.setIsCreateTimeDesc(SortConstant.IS_DESC);
        }
        if (volunteerDTO.getParams() != null){
            String status = (String) volunteerDTO.getParams().get("status");
            if (status != null && status != ""){
                volunteerDTO.getParams().put("currentTime",LocalDateTime.now());
            }
        }
        Long userId = SecurityUtils.getUserId();
        List<VolunteerVO> volunteers =
                volunteerMapper.getSignUpVolunteerList(userId,volunteerDTO);
        for (VolunteerVO volunteer : volunteers) {
            //检查是否签到
            Boolean signIn = volunteerSignListService.checkSign(volunteer.getId(), userId);
            volunteer.setSignIn(signIn);
            volunteer.setSignUp(true);
        }
        //获取已报名志愿服务列表
        return volunteers;
    }

    /**
     * 结束志愿服务
     * @param volunteerId
     * @return
     */
    @Override
    public AjaxResult endVolunteer(Long volunteerId) {
        Volunteer volunteer = volunteerMapper.getVolunteerById(volunteerId);
        Long userId = SecurityUtils.getUserId();
        if (volunteer.getPublisherId() != userId && !SecurityUtils.isAdmin(userId)){
            throw new ServiceException("您没有相关权限");
        }
        //如果志愿服务已经结束
        if (volunteer.getStatus() == VolunteerStatusConstant.VOLUNTEER_IS_END){
            throw new VolunteerException(VolunteerExceptionConstant.VOLUNTEER_HAS_ENDED);
        }
       //修改志愿服务状态
        volunteer.setStatus(VolunteerStatusConstant.VOLUNTEER_IS_END);
        volunteer.setRemark("结束志愿服务");
        int row = volunteerMapper.updateVolunteerById(volunteer);
        //创建消息，异步结算志愿服务
        if (row > 0){
            //推送志愿服务信息已修改通知
            StringBuffer content = new StringBuffer();
            content.append("您报名的志愿服务：")
                    .append("《")
                    .append(volunteer.getTitle())
                    .append("》")
                    .append("已经结束");
            VolunteerMessage msg = VolunteerMessage.builder()
                    .volunteerId(volunteerId.toString())
                    .title("志愿服务已经结束")
                    .typeId(MessageTypeConstant.VOLUNTEER_END)
                    .senderId(SecurityUtils.getUserId())
                    .senderName(SecurityUtils.getUsername())
                    .getterId(SenderAndGetterConstant.VOLUNTEER_ATTEND_LIST)
                    .content(content.toString())
                    .build();
            //将消息转换为json格式
            String msgJSON = JSON.toJSONString(msg);
            //向志愿服务参与者，发出通知
            rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE, RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
        }
        return row > 0 ? AjaxResult.success("结束志愿服务成功") : AjaxResult.error("结束志愿服务失败");
    }

    /**
     * 校验用户权限
     * @param volunteerId
     */
    private void checkUserPermission(Long volunteerId) {
        //查询志愿服务
        Volunteer volunteer = volunteerMapper.getVolunteerById(volunteerId);
        Long userId = SecurityUtils.getUserId();
        //如果该用户不是超级管理员，也不是志愿服务的发布人
        if (!SecurityUtils.isAdmin(userId) && volunteer.getPublisherId() != userId){
            //没有相关权限
            throw new VolunteerException(VolunteerExceptionConstant.USER_NOT_HAVE_PERMISSION);
        }
    }

    /**
     * 开始签到
     * @param volunteerSignDTO
     * @return
     */
    @Override
    public int beginSignIn(VolunteerSignDTO volunteerSignDTO) {
        Long volunteerId = volunteerSignDTO.getVolunteerId();
        //校验用户权限
        checkUserPermission(volunteerId);
        //查找志愿服务
        Volunteer volunteer = volunteerMapper.getVolunteerById(volunteerId);
        //设置当前签到次数
        Integer signNum = volunteer.getSignNum();
        volunteer = Volunteer.builder()
                .id(volunteerId)
                .signNum(signNum + 1)
                .signStatus(VolunteerSignStatusConstant.SIGN_ENABLE)
                .signBeginTime(volunteerSignDTO.getSignBeginTime())
                .signEndTime(volunteerSignDTO.getSignEndTime())
                .build();
        volunteer.setRemark("开始签到");
        return volunteerMapper.updateVolunteerById(volunteer);
    }

    /**
     * 结束签到
     * @param volunteerId
     * @return
     */
    @Override
    public int endSignIn(Long volunteerId) {
        //校验用户权限
        checkUserPermission(volunteerId);
        Volunteer volunteer = Volunteer.builder()
                .id(volunteerId)
                .signStatus(VolunteerSignStatusConstant.SIGN_DISABLE)
                .build();
        volunteer.setRemark("结束签到");
        return volunteerMapper.updateVolunteerById(volunteer);
    }

    /**
     * 审核通过
     * @param volunteerId
     * @return
     */
    @Override
    public AjaxResult approveVolunteer(Long volunteerId) {
        //检查 修改资源服务状态 的权限
        VolunteerVO volunteer = checkUpdateStatusPermission(volunteerId);
        //更新志愿服务
        volunteer.setStatus(VolunteerStatusConstant.APPROVE_PASSED);
        int row = volunteerMapper.updateVolunteerById(volunteer);
        if (row > 0){
            //查询志愿服务
            VolunteerVO volunteer1 = volunteerMapper.getVolunteerById(volunteerId);
            //退回时间币
            Long[] volunteerIds = new Long[1];
            volunteerIds[0] = volunteerId;
            //创建消息，异步执行
            String url = URLConstant.VOLUNTEER_SERVICE_BASE_URL + "/" + volunteer1.getId();
            String volunteerIdsStr = StringUtils.join(volunteerIds, ",");
            VolunteerMessage msg = VolunteerMessage.builder()
                    .volunteerId(volunteerIdsStr)
                    .senderId(999L)
                    .senderName("system")
                    .getterId(SenderAndGetterConstant.PUBLISHER)
                    .typeId(MessageTypeConstant.VOLUNTEER_APPROVE_PASS)
                    .title("志愿服务审核通过")
                    .content("您发布的志愿服务《"+volunteer1.getTitle()+"》审核通过。详情可点击链接查看:"+url)
                    .build();
            //将消息转换为json格式
            String msgJSON = JSON.toJSONString(msg);
            //向志愿服务参与者，发出通知
            rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE, RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
        }
        return row > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 审核不通过
     * @param volunteerId
     * @return
     */
    @Override
    public AjaxResult failVolunteer(Long volunteerId, ExamineDTO examineDTO) {
        //检查 修改资源服务状态 的权限
        VolunteerVO volunteer = checkUpdateStatusPermission(volunteerId);
        volunteer.setStatus(VolunteerStatusConstant.APPROVE_PASSED);
        volunteer.setRemark("审核不通过,理由：" + examineDTO.getRemark());
        int row = volunteerMapper.updateVolunteerById(volunteer);
        if (row > 0){
            //查询志愿服务
            VolunteerVO volunteer1 = volunteerMapper.getVolunteerById(volunteerId);
            //退回时间币
            Long[] volunteerIds = new Long[1];
            volunteerIds[0] = volunteerId;
            //创建消息，异步执行
            String volunteerIdsStr = StringUtils.join(volunteerIds, ",");
            VolunteerMessage msg = VolunteerMessage.builder()
                    .volunteerId(volunteerIdsStr)
                    .senderId(999L)
                    .senderName("system")
                    .getterId(SenderAndGetterConstant.PUBLISHER)
                    .typeId(MessageTypeConstant.VOLUNTEER_APPROVE_FAIL)
                    .title("退回时间币")
                    .content("志愿服务审核不通过，退回时间币：" + volunteer1.getTimeCoin()*volunteer1.getVolunteerNum())
                    .build();
            //将消息转换为json格式
            String msgJSON = JSON.toJSONString(msg);
            //向志愿服务参与者，发出通知
            rabbitTemplate.convertAndSend(ExchangeConstant.VOLUNTEER_MESSAGE_EXCHANGE, RoutingKeyConstant.VOLUNTEER_MESSAGE_ROUTING_KEY,msgJSON);
        }
        return row > 0 ? AjaxResult.success() : AjaxResult.error();
    }


    /**
     * 检查 修改资源服务状态 的权限
     * @param volunteerId
     * @return
     */
    private VolunteerVO checkUpdateStatusPermission(Long volunteerId) {
        //查询志愿服务
        VolunteerVO volunteer = volunteerMapper.getVolunteerById(volunteerId);
        if (volunteer == null){
            throw new ServiceException("未找到志愿服务，id:" + volunteerId);
        }
        //查询用户信息
        Result<LoginUser> result =
                remoteUserService.getUserInfo(SecurityUtils.getUsername(), SecurityConstants.INNER);
        if (result.getData() == null || result.getData().getSysUser() == null){
            throw new ServiceException("查询用户信息失败");
        }
        SysUser sysUser = result.getData().getSysUser();
        //如果不是是管理员和超级管理员
        if (!(sysUser.getRole().equals(999) || sysUser.isAdmin())){
            throw new ServiceException("没有相关权限");
        }
        return volunteer;
    }
}
